package cn.sportvip.service.sport;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.sportvip.dto.sport.CoachDto;
import cn.sportvip.dto.sport.CourseDto;
import cn.sportvip.dto.sport.GymnasiumDto;
import cn.sportvip.entity.sport.Coach;
import cn.sportvip.entity.sport.CoachBasic;
import cn.sportvip.entity.sport.Course;
import cn.sportvip.entity.sport.CourseBasic;
import cn.sportvip.entity.sport.Event;
import cn.sportvip.entity.sport.Gymnasium;
import cn.sportvip.entity.sport.GymnasiumBasic;
import cn.sportvip.entity.sport.ServicePhone;
import cn.sportvip.entity.sport.Tag;
import cn.sportvip.repository.jpa.sport.CoachRepository;
import cn.sportvip.repository.jpa.sport.CourseRepository;
import cn.sportvip.repository.jpa.sport.EventRepository;
import cn.sportvip.repository.jpa.sport.GymnasiumRepository;
import cn.sportvip.repository.jpa.sport.ServicePhoneRepository;
import cn.sportvip.repository.jpa.sport.TagRepository;
import cn.sportvip.repository.mongo.sport.CoachBasicRepository;
import cn.sportvip.repository.mongo.sport.CourseBasicRepository;
import cn.sportvip.repository.mongo.sport.GymnasiumBasicRepository;

/**
 * 后台管理逻辑
 * 
 * @author tao
 */
@Service
public class CmsSportService {

	@Autowired
	private GymnasiumBasicRepository gymnasiumBasicRepository;
	@Autowired
	private GymnasiumRepository gymnasiumRepository;
	@Autowired
	private TagRepository tagRepository;
	@Autowired
	private EventRepository eventRepository;
	@Autowired
	private CoachRepository coachRepository;
	@Autowired
	private CoachBasicRepository coachBasicRepository;
	@Autowired
	private CourseRepository courseRepository;
	@Autowired
	private CourseBasicRepository courseBasicRepository;
	@Autowired
	private ServicePhoneRepository servicePhoneRepository;
	@Autowired
	private SportService sportService;

	// 标签
	/** 增、改标签 */
	@Transactional
	public void createTag(Tag tag) {
		tagRepository.save(tag);
	}

	/** 查标签 */
	@Transactional(readOnly = true)
	public Iterable<Tag> findAllTags() {
		return tagRepository.findAll();
	}

	/** 一个标签 */
	@Transactional(readOnly = true)
	public Tag findOneTag(int id) {
		return tagRepository.findOne(id);
	}

	// 运动项目
	/** 增、改运动项目 */
	@Transactional
	public void createEvent(Event event) {
		if (event.getId() != null) {
			// 修改场馆对应的 event
			Iterable<GymnasiumBasic> gyBasics = gymnasiumBasicRepository
					.findAll();
			for (GymnasiumBasic basic : gyBasics) {
				boolean modified = false;
				for (Event e : basic.getEvents()) {
					if (e.getId().equals(event.getId())) {
						e.setName(event.getName());
						e.setIcon(event.getIcon());
						modified = true;
					}
				}
				if (modified) {
					gymnasiumBasicRepository.save(basic);
				}
			}
			// 修改教练对应的 event
			Iterable<CoachBasic> coBasics = coachBasicRepository.findAll();
			for (CoachBasic basic : coBasics) {
				boolean modified = false;
				for (Event e : basic.getEvents()) {
					if (e.getId().equals(event.getId())) {
						e.setName(event.getName());
						e.setIcon(event.getIcon());
						modified = true;
					}
				}
				if (modified) {
					coachBasicRepository.save(basic);
				}
			}
			// 课程
			Iterable<CourseBasic> courBasics = courseBasicRepository.findAll();
			for (CourseBasic basic : courBasics) {
				boolean modified = false;
				Event courseEvent = basic.getEvent();
				if (courseEvent.getId().equals(event.getId())) {
					courseEvent.setName(event.getName());
					courseEvent.setIcon(event.getIcon());
					modified = true;
				}
				if (modified) {
					courseBasicRepository.save(basic);
				}
			}
		}
		eventRepository.save(event);
	}

	/** 查运动项目 */
	@Transactional(readOnly = true)
	public Iterable<Event> findAllEvents() {
		return eventRepository.findAll();
	}

	/** 添加教练 */
	@Transactional
	public void createCoach(Coach coach, CoachBasic basic, List<Integer> tagIds) {
		coachRepository.save(coach);
		basic.setCoachId(coach.getId());
		coachBasicRepository.save(basic);
	}

	/** 添加课程 */
	@Transactional
	public Course createCourse(Course course, CourseBasic basic, int eventId) {
		if(course.getId() != null){
			Course oldCourse = courseRepository.findOne(course.getId());
			course.setGymnasium(oldCourse.getGymnasium());
			course.setCoach(oldCourse.getCoach());
		}
		courseRepository.save(course);
		basic.setCourseId(course.getId());
		basic.setEvent(eventRepository.findOne(eventId));
		courseBasicRepository.save(basic);
		return course;
	}

	/** 添加场馆 */
	@Transactional
	public void createGymnasium(Gymnasium gymnasium, GymnasiumBasic basic,
			List<Integer> tagIds) {
		if(gymnasium.getId() != null){
			Gymnasium old = gymnasiumRepository.findOne(gymnasium.getId());
			gymnasium.setCoaches(old.getCoaches());
			gymnasium.setCourses(old.getCourses());
		}
		gymnasiumRepository.save(gymnasium);
		basic.setGymnasiumId(gymnasium.getId());
		gymnasiumBasicRepository.save(basic);
	}
	/**添加一个课程给教练*/
	@Transactional
	public void addOneCourseToCoach(int courseId, int coachId){
		// 该课程原来的教练和现在要关联的教练
		Course course = courseRepository.findOne(courseId);
		Coach oldCoach = course.getCoach();
		Coach newCoach = coachRepository.findOne(coachId);
		// 从原来关联的教练中移除
		if(oldCoach != null && !oldCoach.getId().equals(newCoach.getId())){
			Set<Course> courses = oldCoach.getCourses();
			courses.remove(course);
			List<Integer> courseIds = new ArrayList<>(courses.size());
			for(Course c : courses){
				courseIds.add(c.getId());
			}
			addCoursesToCoach(oldCoach.getId(), courseIds);
		}
		// 跟新教练关联
		Set<Course> courses = newCoach.getCourses();
		courses.add(course);
		List<Integer> courseIds = new ArrayList<>(courses.size());
		for(Course c : courses){
			courseIds.add(c.getId());
		}
		addCoursesToCoach(coachId, courseIds);
		
	}
	/**给课程添加教练*/
	@Transactional
	public void addCoursesToCoach(int coachId, List<Integer> courseIds) {
		Coach coach = coachRepository.findOne(coachId);
		CoachBasic basic = coachBasicRepository.findOne(coachId);
		coach.getCourses().clear();
		basic.getAgeRange().clear();
		basic.getEvents().clear();
		basic.setMinPrice(0);
		basic.setHasCourses(false);
		for(Integer courseId : courseIds){
			// 有课
			basic.setHasCourses(true);
			Course course = courseRepository.findById(courseId);
			CourseBasic courseBasic = courseBasicRepository.findOne(courseId);
			// 更新教练价格
			if(coach.getCourses().size() == 0) {
				basic.setMinPrice(course.getPrice());
			} else {
				if(course.getPrice() < basic.getMinPrice()) {
					basic.setMinPrice(course.getPrice());
				}
			}
			// 关联教练
			course.setCoach(coach);
			courseRepository.save(course);
			// 更新教练支持的项目
			basic.getEvents().add(courseBasic.getEvent());
			// 更新教练支持的年龄段
			basic.getAgeRange().addAll(courseBasic.getAge());			
		}
		coachRepository.save(coach);
		coachBasicRepository.save(basic);
	}
	/**添加一个课程到场馆*/
	@Transactional
	public void addOneCourseToGymnasium(int gymnasiumId, int courseId){
		// 课程对应的原来的场馆和现在的场馆
		Course course = courseRepository.findById(courseId);
		Gymnasium newGymnasium = gymnasiumRepository.findOne(gymnasiumId);
		Gymnasium oldGymnasium = course.getGymnasium();
		
		// 把课程从他原来所在的场馆中删除并更新原来场馆的信息
		if(oldGymnasium != null && !newGymnasium.getId().equals(oldGymnasium.getId())){
			Set<Course> courses = oldGymnasium.getCourses();
			courses.remove(course);// 移除
			List<Integer> courseIds = new ArrayList<>(courses.size());
			for(Course c : courses){
				courseIds.add(c.getId());
			}
			addCourseToGymnasium(oldGymnasium.getId(), courseIds);// 更新
		}
		// 把课程加入现在场馆中并更新场馆的信息
		Set<Course> courses = newGymnasium.getCourses();
		courses.add(course);
		List<Integer> courseIds = new ArrayList<>(courses.size());
		for(Course c : courses){
			courseIds.add(c.getId());
		}
		addCourseToGymnasium(gymnasiumId, courseIds);
		
	}
	/**给场馆添加课程*/
	@Transactional
	public void addCourseToGymnasium(int gymnasiumId, List<Integer> courseIds) {
		Gymnasium gymnasium = gymnasiumRepository.findOne(gymnasiumId);
		GymnasiumBasic gymnasiumBasic = gymnasiumBasicRepository.findOne(gymnasiumId);
		// 清空关联
		gymnasium.getCoaches().clear();
		gymnasium.getCourses().clear();
		gymnasiumBasic.getAgeRange().clear();
		gymnasiumBasic.getEvents().clear();
		gymnasiumBasic.setHasCourses(false);
		for(int courseId : courseIds) {
			// 有课
			gymnasiumBasic.setHasCourses(true);
			
			Course course = courseRepository.findOne(courseId);
			CourseBasic basic = courseBasicRepository.findOne(courseId);
			// 更新场馆的最高最低价格
			if(gymnasium.getCourses().size() == 0) {// 新建的场馆没有更新过价格
				gymnasiumBasic.setMaxPrice(course.getPrice());
				gymnasiumBasic.setMinPrice(course.getPrice());
			} else {
				if(course.getPrice() < gymnasiumBasic.getMinPrice()) {
					gymnasiumBasic.setMinPrice(course.getPrice());
				} else if (course.getPrice() > gymnasiumBasic.getMaxPrice()) {
					gymnasiumBasic.setMaxPrice(course.getPrice());
				}
			}
			// 关联课程场馆
			course.setGymnasium(gymnasium);
			courseRepository.save(course);
			// 关联教练到场馆
			Coach coach = course.getCoach();
			gymnasium.getCoaches().add(coach);
			// 更新教练信息
			CoachBasic coachBasic = coachBasicRepository.findOne(coach.getId());
			// 更新教练位置
			coachBasic.setLocation(gymnasiumBasic.getLocation());
			// 更新教练地址
			coachBasic.setAddress(gymnasiumBasic.getAddress());
			coachBasicRepository.save(coachBasic);
			// 更新场馆支持的项目
			gymnasiumBasic.getEvents().add(basic.getEvent());

			// 更新场馆年龄段
			gymnasiumBasic.getAgeRange().addAll(basic.getAge());
			// 更新课程地址
			basic.setAddress(gymnasiumBasic.getAddress());
			courseBasicRepository.save(basic);
		}
 		gymnasiumRepository.save(gymnasium);
		gymnasiumBasicRepository.save(gymnasiumBasic);
	}
	
	/**查找所有教练*/
	public Page<CoachDto> findAllCoaches(int pageNo, int pageSize) {
		Page<Coach> jpa = coachRepository.findAll(new PageRequest(pageNo, pageSize, new Sort("id")));
	
		List<CoachDto> dtos = new ArrayList<CoachDto>(jpa.getNumberOfElements());
		for(Coach c : jpa) {
			dtos.add(sportService.buildCoachDto(c, coachBasicRepository.findOne(c.getId())));
		}
		return new PageImpl<CoachDto>(dtos, new PageRequest(pageNo, pageSize, new Sort("id")), jpa.getTotalElements());
	}
	
	/**查找所有课程*/
	public Page<CourseDto> findAllCourses(int pageNo, int pageSize) {
		Pageable pageable = new PageRequest(pageNo, pageSize);
		Page<Course> jpa = courseRepository.findAll(pageable);
		
		List<CourseDto> dtos = new ArrayList<CourseDto>(jpa.getNumberOfElements());
		for(Course c : jpa) {
			dtos.add(sportService.buildCourseDto(c, courseBasicRepository.findOne(c.getId())));
		}
		return new PageImpl<CourseDto>(dtos, pageable, jpa.getTotalElements());
	}
	
	
	/**查找所有场馆*/
	public Page<GymnasiumDto> findAllGymnasiums(int pageNo, int pageSize) {
		Pageable pageable = new PageRequest(pageNo, pageSize);
		Page<Gymnasium> jpa = gymnasiumRepository.findAll(pageable);
		
		List<GymnasiumDto> dtos = new ArrayList<GymnasiumDto>(jpa.getNumberOfElements());
		for(Gymnasium g : jpa){
			dtos.add(sportService.buildGymnasiumDto(g, gymnasiumBasicRepository.findOne(g.getId())));
		}
		return new PageImpl<GymnasiumDto>(dtos, pageable, jpa.getTotalElements());
	}
	
	/**查找所有客服电话*/
	public Iterable<ServicePhone> findAllServicePhone(){
		return servicePhoneRepository.findAll();
	}
	
	/**增／改service phone*/
	public ServicePhone saveOrUpdateServicePhone(ServicePhone servicePhone){
		return servicePhoneRepository.save(servicePhone);
	}
	
	/**删service phone*/
	public void deleteServicePhone(int id){
		servicePhoneRepository.delete(id);
	}
}
